package zero.tech.games.gate.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import zero.tech.core.data.Resp;
import zero.tech.core.util.DatetimeUtil;
import zero.tech.games.common.ClubMemberUtil;
import zero.tech.games.common.Code;
import zero.tech.games.common.GoldChangeType;
import zero.tech.games.common.QueueConsts;
import zero.tech.games.common.TopicOrder;
import zero.tech.games.common.TradeOperate;
import zero.tech.games.common.UserLastRoomUtil;
import zero.tech.games.common.data.UserLastRoom;
import zero.tech.games.common.topic.GoldAdd;
import zero.tech.games.entity.games.ClubMember;
import zero.tech.games.entity.games.ClubMemberProxy;
import zero.tech.games.entity.games.ClubMemberWaterpak;
import zero.tech.games.entity.log.LogGoldChange;
import zero.tech.games.entity.log.LogSafetyChange;
import zero.tech.games.entity.log.LogTrade;
import zero.tech.games.entity.log.LogWaterRewardGet;
import zero.tech.games.gate.hot.ClubUtil;
import zero.tech.games.gate.mapper.ClubMemberMapper;
import zero.tech.games.gate.mapper.ClubMemberWaterpakMapper;
import zero.tech.games.gate.service.api.ITradeService;
import zero.tech.games.gate.util.PipeiUtil;
import zero.tech.redis.lock.RedisLockUtil;
import zero.tech.redis.lock.RedisLockUtil.LockMethod;
import zero.tech.redis.queue.QueueUtil;
import zero.tech.redis.topic.TopicChannelType;
import zero.tech.redis.topic.service.api.IRedisMsgService;

@Service
public class TradeServiceImpl implements ITradeService{
	@Autowired
	private ClubUtil clubUtil;
	@Autowired
	private UserLastRoomUtil userLastRoomUtil;
	@Autowired
	private ClubMemberUtil clubMemberUtil;
	@Autowired
	private ClubMemberMapper clubMemberMapper;
	@Autowired
	private ClubMemberWaterpakMapper clubMemberWaterpakMapper;
	@Autowired
	private IRedisMsgService redisMsgService;
	@Autowired
	private RedisLockUtil lockUtil;
	@Autowired
	private QueueUtil queueUtil;
	@Autowired
	private PipeiUtil pipeiUtil;
	@Override
	public Resp trade(int club_id, int father_uid, int uid, long gold, int type) {
		Assert.isTrue(gold>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				if(type==0) {
					//上分
					ClubMember clubMember = clubUtil.getClubMember(father_uid, club_id);
					if(clubMember.getTea()<gold) {
						return Resp.build(Code.MONEY_NOT_ENOUGH, "茶叶不够");
					}
					//扣钱
					clubMemberMapper.reduceTea(club_id,father_uid,gold);
					clubMemberMapper.addTea(club_id,uid,gold);
					
					//修改缓存
					String sql="select * from club_member where club_id="+club_id+" and uid="+father_uid+
							" union all select * from club_member where club_id="+club_id+" and uid="+uid;
					List<ClubMember> clubMembers=clubMemberMapper.executeSql(sql);
					clubMemberUtil.setClubMemberBatch(club_id, clubMembers);
					//开始记录金币变化日志
					List<LogGoldChange> logGoldChanges = new ArrayList<>();
					//开始记录交易日志
					List<LogTrade> logTrades = new ArrayList<>();
					for(ClubMember member:clubMembers) {
						int club_id=member.getClub_id();
						int uid=member.getUid();
						if(uid==father_uid) {
							//父级
							LogGoldChange logGoldChange = new LogGoldChange();
							logGoldChange.setClub_id(club_id);
							logGoldChange.setUid(uid);
							long change_num=-gold;
							logGoldChange.setChange_num(change_num);
							logGoldChange.setChange_type(GoldChangeType.SHANGFEN_REDUCE);
							logGoldChange.setChange_desc("代理上分金币减少");
							logGoldChange.setCur_tea(member.getTea());
							logGoldChange.setCur_safety(member.getSafety());
							logGoldChange.setCur_frozen(member.getFrozen());
							logGoldChange.setDay_str(day_str);
							logGoldChange.setCreate_stamp(now);
							logGoldChanges.add(logGoldChange);
							
							//父级上分
							LogTrade logTrade = new LogTrade();
							logTrade.setClub_id(club_id);
							logTrade.setUid(father_uid);
							logTrade.setOther_uid(uid);
							logTrade.setOperate(TradeOperate.SHANGFEN);
							logTrade.setGold(gold);
							logTrade.setCur_tea(member.getTea());
							logTrade.setCur_safety(member.getSafety());
							logTrade.setCur_frozen(member.getFrozen());
							logTrade.setDay_str(day_str);
							logTrade.setCreate_stamp(now);
							logTrades.add(logTrade);
						}else {
							//玩家
							LogGoldChange logGoldChange = new LogGoldChange();
							logGoldChange.setClub_id(club_id);
							logGoldChange.setUid(uid);
							long change_num=gold;
							logGoldChange.setChange_num(change_num);
							logGoldChange.setChange_type(GoldChangeType.SHANGFEN_ADD);
							logGoldChange.setChange_desc("玩家上分金币增加");
							logGoldChange.setCur_tea(member.getTea());
							logGoldChange.setCur_safety(member.getSafety());
							logGoldChange.setCur_frozen(member.getFrozen());
							logGoldChange.setDay_str(day_str);
							logGoldChange.setCreate_stamp(now);
							logGoldChanges.add(logGoldChange);
						}
					}
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_TRADE, logTrades);//推送交易日志
					redisMsgService.pulishRedisTopic(TopicChannelType.CLUB_MEMBER_SHANGFEN, TopicOrder.SHANGFEN, new GoldAdd(gold, uid));
				}else {
					//下分,需要检查被下分者是否有最后的房间
					UserLastRoom userLastRoom=userLastRoomUtil.getUserLastRoom(String.valueOf(uid));
					if(userLastRoom!=null) {
						return Resp.build(Code.USER_IN_ROOM, "玩家还在房间中,不能下分");
					}
					boolean inQueue=pipeiUtil.inQueue(uid);
					if(inQueue) {
						return Resp.build(Code.BE_IN_PIPEIQUEUE, "用户在匹配队列中不能操作下分");
					}
					ClubMember clubMember = clubUtil.getClubMember(uid, club_id);
					if(clubMember.getTea()<gold) {
						return Resp.build(Code.MONEY_NOT_ENOUGH, "茶叶不够");
					}
					clubMemberMapper.reduceTea(club_id,uid,gold);
					clubMemberMapper.addTea(club_id,father_uid,gold);
					//修改缓存
					String sql="select * from club_member where club_id="+club_id+" and uid="+father_uid+
							" union all select * from club_member where club_id="+club_id+" and uid="+uid;
					List<ClubMember> clubMembers=clubMemberMapper.executeSql(sql);
					clubMemberUtil.setClubMemberBatch(club_id, clubMembers);
					//开始记录金币变化日志
					List<LogGoldChange> logGoldChanges = new ArrayList<>();
					//开始记录交易日志
					List<LogTrade> logTrades = new ArrayList<>();
					for(ClubMember member:clubMembers) {
						int club_id=member.getClub_id();
						int uid=member.getUid();
						if(uid==father_uid) {
							//父级
							LogGoldChange logGoldChange = new LogGoldChange();
							logGoldChange.setClub_id(club_id);
							logGoldChange.setUid(uid);
							long change_num=gold;
							logGoldChange.setChange_num(change_num);
							logGoldChange.setChange_type(GoldChangeType.XIAFEN_ADD);
							logGoldChange.setChange_desc("代理下分金币增加");
							logGoldChange.setCur_tea(member.getTea());
							logGoldChange.setCur_safety(member.getSafety());
							logGoldChange.setCur_frozen(member.getFrozen());
							logGoldChange.setDay_str(day_str);
							logGoldChange.setCreate_stamp(now);
							logGoldChanges.add(logGoldChange);
							
							//父级下分
							LogTrade logTrade = new LogTrade();
							logTrade.setClub_id(club_id);
							logTrade.setUid(father_uid);
							logTrade.setOther_uid(uid);
							logTrade.setOperate(TradeOperate.XIAFEN);
							logTrade.setGold(gold);
							logTrade.setCur_tea(member.getTea());
							logTrade.setCur_safety(member.getSafety());
							logTrade.setCur_frozen(member.getFrozen());
							logTrade.setDay_str(day_str);
							logTrade.setCreate_stamp(now);
							logTrades.add(logTrade);
						}else {
							//玩家
							LogGoldChange logGoldChange = new LogGoldChange();
							logGoldChange.setClub_id(club_id);
							logGoldChange.setUid(uid);
							long change_num=-gold;
							logGoldChange.setChange_num(change_num);
							logGoldChange.setChange_type(GoldChangeType.XIAFEN_REDUCE);
							logGoldChange.setChange_desc("玩家下分金币减少");
							logGoldChange.setCur_tea(member.getTea());
							logGoldChange.setCur_safety(member.getSafety());
							logGoldChange.setCur_frozen(member.getFrozen());
							logGoldChange.setDay_str(day_str);
							logGoldChange.setCreate_stamp(now);
							logGoldChanges.add(logGoldChange);
						}
					}
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_TRADE, logTrades);//推送交易日志
				}
				//开始通知账户变化
				clubMemberUtil.notifyClubMemberChange(club_id,father_uid,uid);
				return Resp.build(Code.OK, "交易成功");
			}
		}, "trade_"+club_id+"_"+father_uid, 30);
	}
	@Override
	public Resp frozenPersonGold(int club_id, int father_uid, int uid, long gold) {
		Assert.isTrue(gold>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				//冻结分,需要检查被冻结者是否有最后的房间
				UserLastRoom userLastRoom=userLastRoomUtil.getUserLastRoom(String.valueOf(uid));
				if(userLastRoom!=null) {
					return Resp.build(Code.USER_IN_ROOM, "玩家还在房间中,不能冻结分");
				}
				boolean inQueue=pipeiUtil.inQueue(uid);
				if(inQueue) {
					return Resp.build(Code.BE_IN_PIPEIQUEUE, "用户在匹配队列中不能操作冻结分");
				}
				
				ClubMember clubMember = clubUtil.getClubMember(uid, club_id);
				if(clubMember.getTea()<gold) {
					return Resp.build(Code.MONEY_NOT_ENOUGH, "茶叶不够");
				}
				clubMemberMapper.reduceTeaToFrozen(club_id,uid,gold);
				//修改缓存
				clubMember=clubMemberMapper.selectClubMemberByClubIdAndUid(club_id, uid);
				clubMemberUtil.setClubMember(clubMember);
				//开始记录金币变化日志
				List<LogGoldChange> logGoldChanges = new ArrayList<>();
				LogGoldChange logGoldChange = new LogGoldChange();
				logGoldChange.setClub_id(club_id);
				logGoldChange.setUid(uid);
				long change_num=-gold;
				logGoldChange.setChange_num(change_num);
				logGoldChange.setChange_type(GoldChangeType.FROZEN_REDUCE);
				logGoldChange.setChange_desc("玩家冻结金币减少");
				logGoldChange.setCur_tea(clubMember.getTea());
				logGoldChange.setCur_safety(clubMember.getSafety());
				logGoldChange.setCur_frozen(clubMember.getFrozen());
				logGoldChange.setDay_str(day_str);
				logGoldChange.setCreate_stamp(now);
				logGoldChanges.add(logGoldChange);
				queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
				//开始通知账户变化
				clubMemberUtil.notifyClubMemberChange(club_id,uid);
				return Resp.build(Code.OK, "冻结成功");
			}
		}, "trade_"+club_id+"_"+uid, 30);
	}
	@Override
	public Resp operateBaoxiangui(int club_id, Integer uid, long gold, int type) {
		Assert.isTrue(gold>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				if(type==0) {
					//存分,需要检查被冻结者是否有最后的房间
					UserLastRoom userLastRoom=userLastRoomUtil.getUserLastRoom(String.valueOf(uid));
					if(userLastRoom!=null) {
						return Resp.build(Code.USER_IN_ROOM, "玩家还在房间中,不能存取分");
					}
					boolean inQueue=pipeiUtil.inQueue(uid);
					if(inQueue) {
						return Resp.build(Code.BE_IN_PIPEIQUEUE, "用户在匹配队列中不能操作冻结分");
					}
					//身上钱存入到保险柜
					ClubMember clubMember = clubUtil.getClubMember(uid, club_id);
					if(clubMember.getTea()<gold) {
						return Resp.build(Code.MONEY_NOT_ENOUGH, "茶叶不够");
					}
					clubMemberMapper.reduceTeaToSafety(club_id,uid,gold);
					//修改缓存
					clubMember=clubMemberMapper.selectClubMemberByClubIdAndUid(club_id, uid);
					clubMemberUtil.setClubMember(clubMember);
					//开始记录金币变化日志
					List<LogGoldChange> logGoldChanges = new ArrayList<>();
					LogGoldChange logGoldChange = new LogGoldChange();
					logGoldChange.setClub_id(club_id);
					logGoldChange.setUid(uid);
					long change_num=-gold;
					logGoldChange.setChange_num(change_num);
					logGoldChange.setChange_type(GoldChangeType.CUN_BAOXIANGUI);
					logGoldChange.setChange_desc("玩家存保险柜金币减少");
					logGoldChange.setCur_tea(clubMember.getTea());
					logGoldChange.setCur_safety(clubMember.getSafety());
					logGoldChange.setCur_frozen(clubMember.getFrozen());
					logGoldChange.setDay_str(day_str);
					logGoldChange.setCreate_stamp(now);
					logGoldChanges.add(logGoldChange);
					//开始记录存取记录
					List<LogSafetyChange> logSafetyChanges = new ArrayList<>();
					LogSafetyChange logSafetyChange = new LogSafetyChange();
					logSafetyChange.setClub_id(club_id);
					logSafetyChange.setUid(uid);
					logSafetyChange.setOperate(GoldChangeType.CUN_BAOXIANGUI);
					logSafetyChange.setOp_desc("玩家存保险柜");
					logSafetyChange.setChange_num(change_num);
					logSafetyChange.setCur_tea(clubMember.getTea());
					logSafetyChange.setCur_safety(clubMember.getSafety());
					logSafetyChange.setCur_frozen(clubMember.getFrozen());
					logSafetyChange.setDay_str(day_str);
					logSafetyChange.setCreate_stamp(now);
					logSafetyChanges.add(logSafetyChange);
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_SAFETY_CHANGE, logSafetyChanges);//推送保险柜变化日志
				}else {
					//保险柜钱取出到身上
					ClubMember clubMember = clubUtil.getClubMember(uid, club_id);
					if(clubMember.getSafety()<gold) {
						return Resp.build(Code.MONEY_NOT_ENOUGH, "保险柜茶叶不够");
					}
					clubMemberMapper.reduceSafetyToTea(club_id,uid,gold);
					//修改缓存
					clubMember=clubMemberMapper.selectClubMemberByClubIdAndUid(club_id, uid);
					clubMemberUtil.setClubMember(clubMember);
					//开始记录金币变化日志
					List<LogGoldChange> logGoldChanges = new ArrayList<>();
					LogGoldChange logGoldChange = new LogGoldChange();
					logGoldChange.setClub_id(club_id);
					logGoldChange.setUid(uid);
					long change_num=gold;
					logGoldChange.setChange_num(change_num);
					logGoldChange.setChange_type(GoldChangeType.QU_BAOXIANGUI);
					logGoldChange.setChange_desc("玩家取保险柜金币增加");
					logGoldChange.setCur_tea(clubMember.getTea());
					logGoldChange.setCur_safety(clubMember.getSafety());
					logGoldChange.setCur_frozen(clubMember.getFrozen());
					logGoldChange.setDay_str(day_str);
					logGoldChange.setCreate_stamp(now);
					logGoldChanges.add(logGoldChange);
					//开始记录存取记录
					List<LogSafetyChange> logSafetyChanges = new ArrayList<>();
					LogSafetyChange logSafetyChange = new LogSafetyChange();
					logSafetyChange.setClub_id(club_id);
					logSafetyChange.setUid(uid);
					logSafetyChange.setOperate(GoldChangeType.QU_BAOXIANGUI);
					logSafetyChange.setOp_desc("玩家取保险柜");
					logSafetyChange.setChange_num(change_num);
					logSafetyChange.setCur_tea(clubMember.getTea());
					logSafetyChange.setCur_safety(clubMember.getSafety());
					logSafetyChange.setCur_frozen(clubMember.getFrozen());
					logSafetyChange.setDay_str(day_str);
					logSafetyChange.setCreate_stamp(now);
					logSafetyChanges.add(logSafetyChange);
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
					queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_SAFETY_CHANGE, logSafetyChanges);//推送保险柜变化日志
				}
				//开始通知账户变化
				clubMemberUtil.notifyClubMemberChange(club_id,uid);
				return Resp.build(Code.OK, "冻结成功");
			}
		}, "trade_"+club_id+"_"+uid, 30);
	}
	@Override
	public Resp mailAddPersonGold(int club_id, int uid, Long gold) {
		Assert.isTrue(gold>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				ClubMemberProxy clubMemberProxy = clubUtil.getClubMemberProxy(club_id, uid);
				if(clubMemberProxy==null) {
					return Resp.build(Code.CLUBMEMBER_IS_NOT_EXSIST, "你不在俱乐部");
				}
				clubMemberMapper.addTea(club_id,uid,gold);
				//修改缓存
				ClubMember clubMember=clubMemberMapper.selectClubMemberByClubIdAndUid(club_id, uid);
				clubMemberUtil.setClubMember(clubMember);
				//开始记录金币变化日志
				List<LogGoldChange> logGoldChanges = new ArrayList<>();
				LogGoldChange logGoldChange = new LogGoldChange();
				logGoldChange.setClub_id(club_id);
				logGoldChange.setUid(uid);
				long change_num=gold;
				logGoldChange.setChange_num(change_num);
				logGoldChange.setChange_type(GoldChangeType.MAIL_ADD_GOLD);
				logGoldChange.setChange_desc("玩家领取邮件增加金币");
				logGoldChange.setCur_tea(clubMember.getTea());
				logGoldChange.setCur_safety(clubMember.getSafety());
				logGoldChange.setCur_frozen(clubMember.getFrozen());
				logGoldChange.setDay_str(day_str);
				logGoldChange.setCreate_stamp(now);
				logGoldChanges.add(logGoldChange);
				queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
				//开始通知账户变化
				clubMemberUtil.notifyClubMemberChange(club_id,uid);
				return Resp.build(Code.OK, "操作成功");
			}
		}, "trade_"+club_id+"_"+uid, 30);
	}
	@Override
	public Resp kickClubAddTeaToFather(int club_id,int uid, int father_uid,List<LogGoldChange> logGoldChanges, List<LogTrade> logTrades) {
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				//下分,需要检查被下分者是否有最后的房间
				UserLastRoom userLastRoom=userLastRoomUtil.getUserLastRoom(String.valueOf(uid));
				if(userLastRoom!=null) {
					return Resp.build(Code.USER_IN_ROOM, "玩家还在房间中,不能T出茶馆");
				}
				boolean inQueue=pipeiUtil.inQueue(uid);
				if(inQueue) {
					return Resp.build(Code.BE_IN_PIPEIQUEUE, "用户在匹配队列中不能操作");
				}
				ClubMember clubMember = clubUtil.getClubMember(uid, club_id);
				long gold=clubMember.getTea()+clubMember.getFrozen()+clubMember.getSafety();
				clubMemberMapper.kickoutClear(club_id,uid);
				clubMemberMapper.addTea(club_id,father_uid,gold);
				//修改缓存
				String sql="select * from club_member where club_id="+club_id+" and uid="+father_uid+
						" union all select * from club_member where club_id="+club_id+" and uid="+uid;
				List<ClubMember> clubMembers=clubMemberMapper.executeSql(sql);
				clubMemberUtil.setClubMemberBatch(club_id, clubMembers);
				for(ClubMember member:clubMembers) {
					int club_id=member.getClub_id();
					int uid=member.getUid();
					if(uid==father_uid) {
						//父级
						LogGoldChange logGoldChange = new LogGoldChange();
						logGoldChange.setClub_id(club_id);
						logGoldChange.setUid(uid);
						long change_num=gold;
						logGoldChange.setChange_num(change_num);
						logGoldChange.setChange_type(GoldChangeType.KICK_PERSON_ADD);
						logGoldChange.setChange_desc("T玩家出茶馆增加茶叶");
						logGoldChange.setCur_tea(member.getTea());
						logGoldChange.setCur_safety(member.getSafety());
						logGoldChange.setCur_frozen(member.getFrozen());
						logGoldChange.setDay_str(day_str);
						logGoldChange.setCreate_stamp(now);
						logGoldChanges.add(logGoldChange);
						
						LogTrade logTrade = new LogTrade();
						logTrade.setClub_id(club_id);
						logTrade.setUid(father_uid);
						logTrade.setOther_uid(uid);
						logTrade.setOperate(TradeOperate.KICK_PERSON);
						logTrade.setGold(gold);
						logTrade.setCur_tea(member.getTea());
						logTrade.setCur_safety(member.getSafety());
						logTrade.setCur_frozen(member.getFrozen());
						logTrade.setDay_str(day_str);
						logTrade.setCreate_stamp(now);
						logTrades.add(logTrade);
					}else {
						//玩家
						LogGoldChange logGoldChange = new LogGoldChange();
						logGoldChange.setClub_id(club_id);
						logGoldChange.setUid(uid);
						long change_num=-gold;
						logGoldChange.setChange_num(change_num);
						logGoldChange.setChange_type(GoldChangeType.BE_KICKOUT_REDUCE);
						logGoldChange.setChange_desc("被T出茶馆减少茶叶");
						logGoldChange.setCur_tea(member.getTea());
						logGoldChange.setCur_safety(member.getSafety());
						logGoldChange.setCur_frozen(member.getFrozen());
						logGoldChange.setDay_str(day_str);
						logGoldChange.setCreate_stamp(now);
						logGoldChanges.add(logGoldChange);
					}
				}
				return Resp.build(Code.OK, "交易成功");
			}
		}, "trade_"+club_id+"_"+uid, 30);
	}
	@Override
	public Resp cancleFrozenPersonGold(int club_id, Integer father_uid, int uid, long gold) {
		Assert.isTrue(gold>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				ClubMember clubMember = clubUtil.getClubMember(uid, club_id);
				if(clubMember.getFrozen()<gold) {
					return Resp.build(Code.MONEY_NOT_ENOUGH, "冻结茶叶不够");
				}
				clubMemberMapper.reduceFrozenToTea(club_id,uid,gold);
				//修改缓存
				clubMember=clubMemberMapper.selectClubMemberByClubIdAndUid(club_id, uid);
				clubMemberUtil.setClubMember(clubMember);
				//开始记录金币变化日志
				List<LogGoldChange> logGoldChanges = new ArrayList<>();
				LogGoldChange logGoldChange = new LogGoldChange();
				logGoldChange.setClub_id(club_id);
				logGoldChange.setUid(uid);
				long change_num=-gold;
				logGoldChange.setChange_num(change_num);
				logGoldChange.setChange_type(GoldChangeType.CANCLE_FROZEN_ADD);
				logGoldChange.setChange_desc("玩家解冻金币增加");
				logGoldChange.setCur_tea(clubMember.getTea());
				logGoldChange.setCur_safety(clubMember.getSafety());
				logGoldChange.setCur_frozen(clubMember.getFrozen());
				logGoldChange.setDay_str(day_str);
				logGoldChange.setCreate_stamp(now);
				logGoldChanges.add(logGoldChange);
				queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
				//开始通知账户变化
				clubMemberUtil.notifyClubMemberChange(club_id,uid);
				return Resp.build(Code.OK, "冻结成功");
			}
		},"trade_"+club_id+"_"+uid, 30);
	}
	@Override
	public Resp getExtensionReward(int club_id, int uid, long gold) {
		Assert.isTrue(gold>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {

			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				ClubMemberWaterpak clubMemberWaterpak= clubMemberWaterpakMapper.getClubMemberWaterpak(club_id,uid);
				if(clubMemberWaterpak==null||clubMemberWaterpak.getExtract_total()<gold) {
					return Resp.build(Code.REWARD_NOT_ENOUGH, "奖励不够");
				}
				clubMemberWaterpakMapper.reduceExtract(club_id,uid,gold);
				clubMemberMapper.addTea(club_id,uid,gold);
				//修改缓存
				ClubMember clubMember=clubMemberMapper.selectClubMemberByClubIdAndUid(club_id, uid);
				clubMemberUtil.setClubMember(clubMember);
				//开始记录金币变化日志
				List<LogGoldChange> logGoldChanges = new ArrayList<>();
				LogGoldChange logGoldChange = new LogGoldChange();
				logGoldChange.setClub_id(club_id);
				logGoldChange.setUid(uid);
				long change_num=gold;
				logGoldChange.setChange_num(change_num);
				logGoldChange.setChange_type(GoldChangeType.EXTENSION_REWARD_GET);
				logGoldChange.setChange_desc("玩家提取推广奖励");
				logGoldChange.setCur_tea(clubMember.getTea());
				logGoldChange.setCur_safety(clubMember.getSafety());
				logGoldChange.setCur_frozen(clubMember.getFrozen());
				logGoldChange.setDay_str(day_str);
				logGoldChange.setCreate_stamp(now);
				logGoldChanges.add(logGoldChange);
				//记录提取日志
				LogWaterRewardGet logWaterRewardGet = new LogWaterRewardGet();
				logWaterRewardGet.setClub_id(club_id);
				logWaterRewardGet.setUid(uid);
				logWaterRewardGet.setExtract_gold(gold);
				logWaterRewardGet.setLeft_total(clubMemberWaterpak.getExtract_total()-gold);
				logWaterRewardGet.setDay_str(day_str);
				logWaterRewardGet.setCreate_stamp(now);
				queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_GOLD_CHANGE, logGoldChanges);//推送金币变化日志
				queueUtil.putQueue(QueueConsts.QUEUE_LOG_WATER_REWARD_GET, logWaterRewardGet);
				//开始通知账户变化
				clubMemberUtil.notifyClubMemberChange(club_id,uid);
				return Resp.build(Code.OK, "提取成功");
			}
		}, "trade_"+club_id+"_"+uid, 30);
	}

}
